package com.fancy.recommendation.controller;

import com.fancy.common.dto.response.Result;
import com.fancy.recommendation.dto.request.RecommendationRequestDTO;
import com.fancy.recommendation.dto.response.RecommendationResponseVO;
import com.fancy.recommendation.entity.Recommendation;
import com.fancy.recommendation.service.RecommendationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * 推荐控制器
 *
 * @author fancy
 */
@Api(tags = "推荐服务")
@Slf4j
@RestController
@RequestMapping("/api/v1/recommendations")
@RequiredArgsConstructor
public class RecommendationController {

    private final RecommendationService recommendationService;

    @ApiOperation(value = "获取个性化推荐", notes = "获取用户个性化推荐内容")
    @GetMapping("/personal")
    public Result<RecommendationResponseVO.RecommendationListVO> getPersonalRecommendations(
            @Valid @ModelAttribute RecommendationRequestDTO request) {

        try {
            RecommendationResponseVO.RecommendationListVO recommendations =
                recommendationService.getPersonalRecommendations(request);
            return Result.success(recommendations);
        } catch (Exception e) {
            log.error("获取个性化推荐失败", e);
            return Result.fail("获取推荐失败");
        }
    }

    @ApiOperation(value = "获取相似推荐", notes = "根据指定内容获取相似推荐")
    @GetMapping("/similar/{targetType}/{targetId}")
    public Result<List<RecommendationResponseVO>> getSimilarRecommendations(
            @ApiParam(value = "目标类型", required = true) @PathVariable String targetType,
            @ApiParam(value = "目标ID", required = true) @PathVariable Long targetId,
            @ApiParam(value = "推荐数量") @RequestParam(defaultValue = "10") Integer limit) {

        try {
            List<Recommendation> recommendations = recommendationService.getSimilarRecommendations(
                targetType, targetId, limit);

            List<RecommendationResponseVO> result = recommendations.stream()
                .map(this::convertToVO)
                .collect(java.util.stream.Collectors.toList());

            return Result.success(result);
        } catch (Exception e) {
            log.error("获取相似推荐失败: targetType={}, targetId={}", targetType, targetId, e);
            return Result.fail("获取相似推荐失败");
        }
    }

    @ApiOperation(value = "刷新推荐", notes = "刷新用户的推荐内容")
    @PostMapping("/refresh")
    public Result<Void> refreshRecommendations(
            @ApiParam(value = "用户ID", required = true) @RequestParam Long userId) {

        try {
            recommendationService.refreshUserRecommendations(userId);
            return Result.success(null);
        } catch (Exception e) {
            log.error("刷新推荐失败: userId={}", userId, e);
            return Result.fail("刷新推荐失败");
        }
    }

    @ApiOperation(value = "推荐反馈", notes = "用户对推荐内容的反馈")
    @PostMapping("/feedback")
    public Result<Void> submitFeedback(
            @ApiParam(value = "推荐ID", required = true) @RequestParam Long recommendationId,
            @ApiParam(value = "反馈类型", required = true) @RequestParam String feedback) {

        try {
            recommendationService.updateRecommendationFeedback(recommendationId, feedback);
            return Result.success(null);
        } catch (Exception e) {
            log.error("提交推荐反馈失败: recommendationId={}, feedback={}", recommendationId, feedback, e);
            return Result.fail("提交反馈失败");
        }
    }

    @ApiOperation(value = "获取推荐历史", notes = "获取用户的推荐历史记录")
    @GetMapping("/history")
    public Result<List<RecommendationResponseVO>> getRecommendationHistory(
            @ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
            @ApiParam(value = "推荐类型") @RequestParam(required = false) String recType,
            @ApiParam(value = "数量限制") @RequestParam(defaultValue = "20") Integer limit) {

        try {
            List<Recommendation> recommendations = recommendationService.getCachedRecommendations(
                userId, recType, limit);

            List<RecommendationResponseVO> result = recommendations.stream()
                .map(this::convertToVO)
                .collect(java.util.stream.Collectors.toList());

            return Result.success(result);
        } catch (Exception e) {
            log.error("获取推荐历史失败: userId={}", userId, e);
            return Result.fail("获取推荐历史失败");
        }
    }

    /**
     * 转换为VO对象
     */
    private RecommendationResponseVO convertToVO(Recommendation recommendation) {
        RecommendationResponseVO vo = new RecommendationResponseVO();
        vo.setRecommendationId(recommendation.getId());
        vo.setRecType(recommendation.getRecType());
        vo.setTargetId(recommendation.getTargetId());
        vo.setTargetType(recommendation.getTargetType());
        vo.setScore(recommendation.getScore());
        vo.setReason(recommendation.getReason());
        vo.setAlgorithm(recommendation.getAlgorithm());
        vo.setCreateTime(recommendation.getCreateTime());
        vo.setExpireTime(recommendation.getExpireTime());
        return vo;
    }
}
